﻿using System.Collections.Generic;
using System.Linq;

namespace Tuxedo.Compile
{
	internal class MethodDefinition : IFPClassMember
	{
		public Visibility Visibility { get; private set; }
		public bool IsStatic { get; private set; }
		public string Name { get; private set; }
		public UnverifiedType Type { get; private set; }
		public UnverifiedType[] ParameterTypes { get; private set; }
		public string[] ParameterNames { get; private set; }
		public bool IsOverride { get; private set; }
		public CodeLine[] Code { get; private set; }
		public bool IsDeclarationOnly { get; private set; }
		public bool IsAbstract { get; private set; }
		public string[] SpecialParams { get; private set; }
		public UnverifiedType TypeParam { get; private set; }
		public override MemberAttribute[] Attributes { get { return this.attributes; } }
		private MemberAttribute[] attributes;

		public MethodDefinition(
			Visibility visibility,
			bool isStatic,
			string name,
			UnverifiedType outputType,
			IList<string> parameterNames,
			IList<UnverifiedType> parameterTypes,
			bool isOverride,
			IList<CodeLine> body,
			bool isAbstract,
			IList<string> specialParams,
			UnverifiedType typeParam,
			IList<MemberAttribute> attributes)
		{
			this.Visibility = visibility;
			this.IsStatic = isStatic;
			this.Name = name;
			this.Type = outputType;
			this.ParameterNames = parameterNames.ToArray();
			this.ParameterTypes = parameterTypes.ToArray();
			this.IsOverride = isOverride;
			this.Code = body != null ? body.ToArray() : null;
			this.IsAbstract = isAbstract;
			this.SpecialParams = specialParams.ToArray();
			this.TypeParam = typeParam;
			this.attributes = attributes.ToArray();

			if (isAbstract != (body == null))
			{
				throw new System.Exception(
					isAbstract
						? "Abstract methods cannot have a body declaration."
						: "No body declaration was found for non abstract method.");
			}
		}
	}
}
